/**
 * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */

package com.ziguang.redwood;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.beetl.core.GroupTemplate;
import org.beetl.core.resource.FileResourceLoader;
import org.beetl.ext.jfinal.BeetlRenderFactory;

import com.alibaba.druid.filter.config.ConfigTools;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.ActionReporter;
import com.jfinal.ext.handler.RenderingTimeHandler;
import com.jfinal.ext.handler.UrlSkipHandler;
import com.jfinal.ext.log.Slf4jLogFactory;
import com.jfinal.ext.route.AutoBindRoutes;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.SqlReporter;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.plugin.druid.IDruidStatViewAuth;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.ziguang.common.interceptor.GlobalActionInterceptor;
import com.ziguang.redwood.model._MappingKit;


public class AppConfig extends JFinalConfig {
	
	
	/**
	 * 配置常量
	 */
	@Override
	public void configConstant(Constants me) {
		// 加载少量必要配置，随后可用PropKit.get(...)获取值
		PropKit.use("application.properties");
		me.setDevMode(PropKit.getBoolean("app.devmode", false));
		
		// 错误页面设置
		me.setError401View("/error/401.html");
		me.setError403View("/error/403.html");
		me.setError404View("/error/404.html");
		me.setError500View("/error/500.html");
		 
		// 設置日志實現爲日誌處理門面Slf4j框架
		me.setLogFactory(new Slf4jLogFactory());
		
		// 设置JFinal Action Report时机
		ActionReporter.setReportAfterInvocation(false);
		
		// 设置beetle模板引擎
		BeetlRenderFactory beetlRF = new BeetlRenderFactory(new FileResourceLoader(PathKit.getWebRootPath() + PropKit.get("web.view.dir")));
		//me.setMainRenderFactory(new BeetlRenderFactory(PropKit.get("web.view.dir")));
		me.setMainRenderFactory(beetlRF);
		// 获取GroupTemplate ,可以设置共享变量等操作
        GroupTemplate groupTemplate = BeetlRenderFactory.groupTemplate;
        groupTemplate.setSharedVars((Map) PropKit.getProp().getProperties());
	}
	
	/**
	 * 配置路由
	 */
	@Override
	public void configRoute(Routes me) {
		
		/* 默认配置路由方式 */ 
		// 第三个参数为该Controller的视图存放路径
		// 第三个参数省略时默认与第一个参数值相同，在此即为 "/"
		//me.add("/", DefaultFrontController.class, "/views");	//默认首页 
		/* 自动扫描 [注解方式] */
		AutoBindRoutes autoBindRoutes = new AutoBindRoutes().autoScan(false).includeAllJarsInLib(false);	//禁止自动投其扫描
		List excludeClasses = new ArrayList();
//		excludeClasses.add(ApiController.class);	// 排除自动扫描的controller
		autoBindRoutes.addExcludeClasses(excludeClasses);
		me.add(autoBindRoutes);
		
	}
	
	/**
	 * 为方便JFinalGenerator使用，故单独创建该方法
	 * @return DruidPlugin
	 */
	public static DruidPlugin createDruidPlugin() {
		/*
		 * String encryptStr = ConfigTools.encrypt("admin888");	//数据库密码加密
		 */
		String dbPassword = PropKit.get("db.default.password").trim();
		try {
			dbPassword = ConfigTools.decrypt(dbPassword);	//数据库密码解密
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new DruidPlugin(PropKit.get("db.default.url"), PropKit.get("db.default.user"), dbPassword);
	}

	/**
	 * 配置插件
	 */
	@Override
	public void configPlugin(Plugins me) {
		// DruidPlugin 数据库连接池插件
		DruidPlugin dp = createDruidPlugin();
		dp.setInitialSize(PropKit.getInt("db.default.initsize", 10));
		dp.setMaxActive(PropKit.getInt("db.default.maxactive", 100));
		dp.addFilter(new StatFilter());
		WallFilter wall = new WallFilter();
		wall.setDbType(JdbcConstants.MYSQL);
		dp.addFilter(wall);
		me.add(dp);
		
		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
		//arp.setDialect(new PostgreSqlDialect());
		arp.setDialect(new MysqlDialect());
		arp.setShowSql(PropKit.getBoolean("db.showsql", false));
		me.add(arp);
		SqlReporter.setLog(true); //SQL保存至日誌
		
		// 所有配置在 MappingKit 中搞定
		_MappingKit.mapping(arp);
		
		/* 开启EhCache缓存   */
		EhCachePlugin ecp = new EhCachePlugin();
		me.add(ecp);
		
		// 加载Shiro插件   [不建议此处配置]
		//me.add(new ShiroPlugin(routes));
				 
		/*非注解方式
		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(c3p0Plugin);
		arp.setShowSql(PropKit.getBoolean("db.showsql", false));
		me.add(arp);
		
		arp.addMapping("cwo_news_content", "content_id", News.class); // 映射cwo_news_content 表到 News模型
		arp.addMapping("cwo_news_column", "news_id", Catalog.class); // 映射cwo_news_column 表到 Catalog模型
		arp.addMapping("cwo_wx_plan", "plan_id", Plan.class); //
		arp.addMapping("cwo_wx_plan_join", "join_id", PlanJoin.class); // 
		arp.addMapping("cwo_wx_user", "user_id", User.class); // 
		arp.addMapping("cwo_wx_user_amount", "amount_id", UserAmount.class); // 
		*/
		
		/* 开启ActiveRecord自动注解绑定  
		AutoTableBindPlugin atbp = new AutoTableBindPlugin(c3p0Plugin, SimpleNameStyles.LOWER);
		atbp.setShowSql(PropKit.getBoolean("db.showsql", false));
		me.add(atbp);
		*/
		
		/* 开启Redis缓存   */
//		Prop pr = PropKit.use("redis.properties");
//		RedisPlugin redis = new RedisPlugin(pr.get("redis.cacheName"), pr.get("redis.serverHost"), pr.getInt("redis.serverPort"), pr.getInt("redis.timeout", 3000), pr.get("redis.serverAuth"));
//		redis.getJedisPoolConfig().setMaxTotal(pr.getInt("redis.MaxTotal"));
//		redis.getJedisPoolConfig().setMaxIdle(pr.getInt("redis.MaxIdle"));
//		redis.getJedisPoolConfig().setTestOnBorrow(pr.getBoolean("redis.TestOnBorrow"));
//		redis.getJedisPoolConfig().setTestOnReturn(pr.getBoolean("redis.TestOnReturn"));
//		me.add(redis);
	}

	/**
	 * 配置全局拦截器
	 */
//	@Override
//	public void configInterceptor(Interceptors me) {
//		//	前端用户权限拦截器
//		me.add(new AuthzInterceptor());
//		// shiro Interceptor
//		me.add(new ShiroInterceptor());
//	}

	/**
	 * 配置处理器
	 * modify zhuangjiali 2016.11.3
	 */
	@Override
	public void configHandler(Handlers me) {
		//me.add(new ContextPathHandler("ctx"));
		
		//me.add(new CacheControlHeaderHandler(30*24*60));//开户页面静态文件缓存  一个月
		
		me.add(new UrlSkipHandler("^/websocket/[\\w]*", true));
		
		me.add(new RenderingTimeHandler());//执行时间统计
		
		DruidStatViewHandler dsvh =  new DruidStatViewHandler("/druid", new IDruidStatViewAuth() {
			@Override
			public boolean isPermitted(HttpServletRequest request) {
				/* TODO druid权限待配置
				// 这里只是简单的判断访问者是否登录，还可以做更加细致的权限控制
                User user=(User) request.getSession().getAttribute("user");
                if(user==null){
                    return false;
                }
                return "admin".equals(user.getStr("uname"));
                */
				return true;
			}
		});
		me.add(dsvh);
		 
		/*添加全局变量另一种写法
		try {
			FreeMarkerRender.getConfiguration().setSharedVariable("v", System.currentTimeMillis());
		} catch (TemplateModelException e) {
			e.printStackTrace();
		}
		*/
	}
	
//	@Override
//	public void afterJFinalStart() {
//        // 1.5 之后支持redis存储access_token、js_ticket，需要先启动RedisPlugin
////        ApiConfigKit.setAccessTokenCache(new RedisAccessTokenCache());
//        // 1.6新增的2种初始化
////        ApiConfigKit.setAccessTokenCache(new RedisAccessTokenCache(Redis.use("weixin")));
////        ApiConfigKit.setAccessTokenCache(new RedisAccessTokenCache("weixin"));
//
//        ApiConfig ac = new ApiConfig();
//        // 配置微信 API 相关参数
//        ac.setToken(PropKit.get("token"));
//        ac.setAppId(PropKit.get("appId"));
//        ac.setAppSecret(PropKit.get("appSecret"));
//        ac.setToken(PropKit.get("token"));
//        
//        /**
//         *  是否对消息进行加密，对应于微信平台的消息加解密方式：
//         *  1：true进行加密且必须配置 encodingAesKey
//         *  2：false采用明文模式，同时也支持混合模式
//         */
//        ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
//        ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));
//
//        /**
//         * 多个公众号时，重复调用ApiConfigKit.putApiConfig(ac)依次添加即可，第一个添加的是默认。
//         */
//        ApiConfigKit.putApiConfig(ac);
//        ApiConfigKit.setDevMode(true);
//        // 微信 WxSession的配置
//        // 启用默认的Session管理器
//        // ApiConfigKit.enableDefaultWxSessionManager();
//        // 启用redis Session管理器
//        //ApiConfigKit.setWxSessionManager(new RedisWxSessionManager());
//        // 支持redis存储access_token、js_ticket，需要先启动RedisPlugin
//        //ApiConfigKit.setAccessTokenCache(new RedisAccessTokenCache());
//        /**
//         * 1.9 新增LocalTestTokenCache用于本地和线上同时使用一套appId时避免本地将线上AccessToken冲掉
//         * @see WeixinApiController#getToken()
//         */
//        boolean isLocal = false;
//        if (isLocal) {
//            String onLineTokenUrl = "http://localhost:8080/fhl/weixin/getLocalToken";
//            ApiConfigKit.setAccessTokenCache(new LocalTestTokenCache(onLineTokenUrl));
//        }
//        
//    }

	/**
	 * 建议使用 maven方式启动项目 命令：clean compile tomcat7:run
	 * 运行此 main 方法可以启动项目，此main方法可以放置在任意的Class类定义中，不一定要放于此
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
//		JFinal.start("webapp", 80, "/", 5);
		String encryptStr = ConfigTools.encrypt("123456");	//数据库密码加密
		System.out.println(encryptStr);
	}

//	@Override
//	public void configPlugin(Plugins me) {
//		// TODO Auto-generated method stub
//		
//	}
	
	@Override
	public void configInterceptor(Interceptors me) {
		// TODO Auto-generated method stub
		// 添加控制层全局拦截器
		me.addGlobalActionInterceptor(new GlobalActionInterceptor());
	}
}
